package com.example.listener;

import cn.hutool.json.JSONUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.example.enums.CodeEnum;
import com.example.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Author 王鹤蒲
 * @Date 2023 11 09
 */

@Slf4j
public abstract class ExcelReadListener<T> extends AnalysisEventListener<T> {

    private static final int BATCH_COUNT=10000;

    private final List<T> dataList=new ArrayList<T>();

    private Map<Integer,String> headMap;

    private Map<String,Object> params;


    public List<T> getDataList(){
        return this.dataList;
    }

    public Map<Integer,String> getHeadMap(){
        return this.headMap;
    }

    @Override
    public void onException(Exception exception, AnalysisContext context) throws Exception {
        if(exception instanceof ExcelDataConvertException){
         ExcelDataConvertException excelDataConvertException=(ExcelDataConvertException)exception;
         log.error("第"+excelDataConvertException.getRowIndex()+"行"+excelDataConvertException.getColumnIndex()+"列数据，解析异常");
         throw new ServiceException(CodeEnum.DATA_PARSING_ERROR.getCode(), "第"+excelDataConvertException.getRowIndex()+"行"+excelDataConvertException.getColumnIndex()+"列数据，解析异常");
        }
    }

    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
      this.headMap=headMap;
    }

    @Override
    public void invoke(T t, AnalysisContext analysisContext) {
        log.info("已读取一条数据:{}", JSONUtil.toJsonStr(t));
         dataList.add(t);
         if(dataList.size()>=BATCH_COUNT){
             saveData();
             dataList.clear();
         }
    }


    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
          saveData();
          dataList.clear();
          log.info("所有数据解析完成");
    }


    public abstract boolean saveData();

}
